package cn.server.util;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import cn.server.IBusiness;
import cn.server.IServer;
import cn.server.conf.ServerParam;

/**
 * The Class ServerConfUtil.
 */
@SuppressWarnings("all")
public class ServerConfUtil {
	
	/** Logger for this class. */
	private static final Log logger = LogFactory.getLog(ServerConfUtil.class);

	/** The list. */
	private static List<IServer> list = new ArrayList<IServer>();

	/** The handler map. */
	private static Map<String, String> handlerMap = new HashMap<String, String>();

	/** The sql map. */
	private static Map<String, String> sqlMap = new HashMap<String, String>();

	static {
		init();
	}

	/**
	 * The Constructor.
	 */
	private ServerConfUtil() {
	}

	/**
	 * Inits the.
	 */
	private static void init() {
		try {
			Document doc = new SAXReader().read(new File("config/monitorserver.xml"));
			Element root = doc.getRootElement();
			List<Element> serverList = root.elements("server");
			if (serverList == null)
				return;
			parseServer(serverList);
			parseHandler(root);
			parseSQL(root);
		} catch (Throwable e) {
			logger.error("error parse monitorserver.xml", e);
		}
	}

	/**
	 * 获取sql语句.
	 *
	 * @param key the key
	 * @return the sql
	 */
	public static String getSql(String key) {
		return sqlMap.get(key);
	}

	/**
	 * Gets the handler.
	 *
	 * @param key the key
	 * @return the handler
	 * @throws Exception the exception
	 */
	public static IBusiness getHandler(String key) throws Exception {
		String cls = handlerMap.get(key);
		if (StringUtils.isBlank(cls))
			return null;
		return (IBusiness) Class.forName(cls).newInstance();
	}

	/**
	 * Parses the sql.
	 *
	 * @param root the root
	 * @throws Exception the exception
	 */
	private static void parseSQL(Element root) throws Exception {
		parseNormal(root, "sql", sqlMap);
	}

	/**
	 * Parses the handler.
	 *
	 * @param root the root
	 * @throws Exception the exception
	 */
	private static void parseHandler(Element root) throws Exception {
		parseNormal(root, "handlers", handlerMap);
	}

	/**
	 * Parses the normal.
	 *
	 * @param root the root
	 * @param elName the el name
	 * @param map the map
	 * @throws Exception the exception
	 */
	private static void parseNormal(Element root, String elName, Map<String, String> map) throws Exception {
		Element element = root.element(elName);
		if (element == null)
			return;
		List<Element> elements = element.elements();
		if (elements == null)
			return;
		for (int i = 0; i < elements.size(); i++) {
			Element el = elements.get(i);
			map.put(el.getName(), el.getTextTrim());
		}
	}

	/**
	 * Parses the server.
	 *
	 * @param serverList the server list
	 * @throws Exception the exception
	 */
	private static void parseServer(List<Element> serverList) throws Exception {
		for (int i = 0; i < serverList.size(); i++) {
			Element serverEl = serverList.get(i);
			String sc = serverEl.attributeValue("class");
			if (StringUtils.isBlank(sc)) {
				logger.warn("server element class is null,skip!");
				continue;
			}
			IServer server = (IServer) Class.forName(sc).newInstance();
			Element paramEl = serverEl.element("param");
			if (paramEl == null) {
				logger.warn("param element is null,skip!");
				continue;
			}
			String paramCls = paramEl.attributeValue("class");
			if (StringUtils.isBlank(paramCls)) {
				logger.warn("param element class is null,skip!");
				continue;
			}
			ServerParam sp = (ServerParam) Class.forName(paramCls).newInstance();
			List<Element> paramEls = paramEl.elements();
			if (paramEls != null) {
				for (int j = 0; j < paramEls.size(); j++) {
					Element el = paramEls.get(j);
					BeanUtils.copyProperty(sp, el.getName(), el.getTextTrim());
				}
			}
			server.setParam(sp);
			Element confEl = serverEl.element("conf");
			if (confEl != null) {
				String confCls = confEl.attributeValue("class");
				if (StringUtils.isNotBlank(confCls))
					server.setConfClass(confCls);
			}
			list.add(server);
		}
	}

	/**
	 * Parses the server list.
	 *
	 * @return the list< i server>
	 */
	public static List<IServer> parseServerList() {
		return list;
	}
}